home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-19 | 6.5 KB | 203 lines | [TEXT/MPS ] |
- # Build token and operator tables ("toktab.c" and "optab.c")
- # from token description file "tokens.txt" and skeleton operator
- # state tables in "optab.txt".
-
- global token, tokval, bflag, eflag, head, oper, tail, count
- global restable, opertable, flagtable
- global tokfile, opfile, toktab, optab
-
- procedure tokpat()
- if match("#") then return token := tab(0)
- if tab(many(' \t')) & (token := tab(upto(' \t'))) &
- tab(many(' \t')) & (tokval := (tab(upto(' \t') | 0)))
- then return (tab(upto('b')) & (bflag := move(1))) | (bflag := "") &
- ((tab(upto('e')) & (eflag := move(1))) | (eflag := "")) & pos(0)
- end
-
- procedure operpat()
- return (head := tab(upto('['))) & ="[ ]" &
- (tail := (tab(upto('"')) || move(1) ||
- (oper := tab(upto('"'))) || move(1) || tab(0)))
- end
-
- procedure main()
- local line, letter, lastletter
- restable := table()
- opertable := table()
- flagtable := table("")
- flagtable[""] := "0,"
- flagtable["b"] := "Beginner,"
- flagtable["e"] := "Ender,"
- flagtable["be"] := "Beginner+Ender,"
- count := 0
- lastletter := ""
-
- tokfile := open("tokens.txt") | stop("unable to open \"tokens.txt\"")
- opfile := open("optab.txt") | stop("unable to open \"optab.txt\"")
- toktab := open("toktab.c","w")
- optab := open("optab.c","w")
-
- # Skip the first few (non-informative) lines of "tokens.txt"
-
- garbage()
-
- # Output header for "toktab.c"
- write(toktab,"#include \"../h/gsupport.h\"")
- write(toktab,"#include \"tproto.h\"")
- write(toktab,"#include \"trans.h\"")
- write(toktab,"#include \"tlex.h\"")
- write(toktab,"#include \"token.h\"")
- write(toktab)
- write(toktab,"/*")
- write(toktab," * Token table - contains an entry for each token type")
- write(toktab," * with printable name of token, token type, and flags")
- write(toktab," * for semicolon insertion.")
- write(toktab," */")
- write(toktab)
- write(toktab,"struct toktab toktab[] = {")
- write(toktab,"/* token\t\ttoken type\tflags */")
- write(toktab)
- write(toktab," /* primitives */")
-
- # Read primitive tokens and output to "toktab.c"
-
- repeat {
- write(toktab,makeline(token,tokval,bflag || eflag,count))
- count +:= 1
- line := read(tokfile) | stop("premature end-of-file")
- line ? tokpat() | break
- }
-
- # Skip some more garbage lines
-
- garbage()
-
- # Output some more comments
-
- write(toktab)
- write(toktab," /* reserved words */")
-
- # Read in reserved words, output them,
- # and build table of first letters.
-
- repeat {
- write(toktab,makeline(token,tokval,bflag || eflag,count))
- letter := token[1]
- if letter ~== lastletter then {
- lastletter := letter
- restable[letter] := count
- }
- count +:= 1
- line := read(tokfile) | stop("premature end-of-file")
- if line ? tokpat() then next else break
- }
-
- # Skip more garbage
-
- garbage()
-
- # Another comment
-
- write(toktab)
- write(toktab," /* operators */")
-
- # Read in operators, output them, and build table
-
- repeat {
- write(toktab,makeline(token,tokval,bflag || eflag,count))
- opertable[token] := count
- if not match("#",token) then count +:= 1
- line := read(tokfile) | stop("premature end-of-file")
- line ? tokpat() | break
- }
- eof()
- end
-
- procedure eof() # output end of token table and reserveed word first-letter index.
- local line
- write(toktab,makeline("end-of-file","0","",""))
- write(toktab," };")
- write(toktab)
- write(toktab,"/*")
- write(toktab," * restab[c] points to the first reserved word in toktab which")
- write(toktab," * begins with the letter c.")
- write(toktab," */")
- write(toktab)
- write(toktab,"#if !EBCDIC")
- write(toktab,"struct toktab *restab[] = {")
- write(toktab,makeres("abcd"))
- write(toktab,makeres("efgh"))
- write(toktab,makeres("ijkl"))
- write(toktab,makeres("mnop"))
- write(toktab,makeres("qrst"))
- write(toktab,makeres("uvwx"))
- write(toktab,makeres("yz"))
- write(toktab," };")
-
- # This really is faked -- need fixing if anything changes.
- write(toktab,"#else /* !EBCDIC */")
- write(toktab, "struct toktab *restab[] = {")
- write(toktab, " NULL ,&toktab[ 6],&toktab[ 8], /* 81-83 abc */")
- write(toktab, " &toktab[10],&toktab[12],&toktab[15],&toktab[16], /* 84-87 defg */")
- write(toktab, " NULL ,&toktab[17],NULL ,NULL , /* 88-8B hi.. */")
- write(toktab, " NULL ,NULL ,NULL ,NULL , /* 8C-8F .... */")
- write(toktab, "")
- write(toktab, " NULL ,NULL ,NULL ,&toktab[19], /* 90-93 .jkl */")
- write(toktab, " NULL ,&toktab[21],&toktab[23],&toktab[24], /* 94-97 mnop */")
- write(toktab, " NULL ,&toktab[25],NULL ,NULL , /* 98-9B qr.. */")
- write(toktab, " NULL ,NULL ,NULL ,NULL , /* 9C-9F .... */")
- write(toktab, "")
- write(toktab, " NULL ,NULL ,&toktab[28],&toktab[30], /* A0-A3 ..st */")
- write(toktab, " &toktab[32],NULL ,&toktab[33],NULL, /* A4-A7 uvwx */")
- write(toktab, " NULL ,NULL , /* A8-AB yz */")
- write(toktab, " };")
- write(toktab, "#endif /* !EBCDIC */")
-
- close(toktab)
-
- # Read through operator state table skeleton, inserting
- # token numbers for operators.
-
- repeat {
- while line := read(opfile) | break break do {
- if line ? operpat() then break
- else write(optab,line)
- }
- if /opertable[oper] then write(&errout,"no entry for",oper)
- else {
- # write(&errout,"oper=",oper,"; index=",opertable[oper])
- write(optab,head,"[",right(opertable[oper],3),"]",tail)
- }
- }
- end
-
- procedure makeline(token,tokval,flag,count) # build an output line for token table.
- local line
- if match("#",token) then return token
- line := left(" \"" || token || "\",",22) || left(tokval || ",",15)
- flag := flagtable[flag]
- if count ~=== "" then flag := left(flag,19)
- line ||:= flag
- if count ~=== "" then line ||:= "/* " || right(count,3) || " */"
- return line
- end
-
- procedure makeres(lets) # build an output line for reserved word index.
- local let, letters, line
- line := " "
- letters := lets
- every let := !lets do
- if \restable[let] then {
- # write(&errout,"let=",let,"; index=",restable[let])
- line ||:= "&toktab[" || right(restable[let],2) || "], "
- }
- else line ||:= "NULL, "
- return left(line,55) || "/* " || letters || " */"
- end
-
- procedure garbage()
- local line
- while line := read(tokfile) | stop("premature end-of-file") do
- if line ? tokpat() then return
- end
-